package com.dhecp.project.system.controller;

import com.alibaba.fastjson.JSON;
import com.dhecp.common.config.Global;
import com.dhecp.common.core.controller.BaseController;
import com.dhecp.common.core.domain.AjaxResult;
import com.dhecp.common.core.page.TableDataInfo;
import com.dhecp.common.utils.StringUtils;
import com.dhecp.common.utils.security.RsaUtils;
import com.dhecp.framework.shiro.realm.CustomUsernamePasswordToken;
import com.dhecp.framework.util.ShiroUtils;
import com.dhecp.framework.web.domain.server.Sys;
import com.dhecp.project.system.domain.SysSetting;
import com.dhecp.project.system.domain.SysUserInfo;
import com.dhecp.project.system.service.SysDictionaryForModuleService;
import com.dhecp.project.system.service.SysSettingService;
import com.dhecp.project.system.service.SysUserInfoService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName SysLoginController
 * @Description TODO
 * @Author alula
 * @Date 2020-06-24 15:08
 */
@Controller
public class SysLoginController extends BaseController{

    @Autowired
    private SysSettingService settingService;

    @Autowired
    private SysUserInfoService userInfoService;
    
    @Autowired
    private SysDictionaryForModuleService dictionaryForModuleService;

    @RequestMapping(value = "/index")
    @ResponseBody
    public AjaxResult index()
    {
        return AjaxResult.success("A页面");
    }

    @RequestMapping(value = "/about")
    @ResponseBody
    public AjaxResult about()
    {
        return AjaxResult.success("B页面");
    }

    /**获取H5部署平台**/
    @RequestMapping("/getDeployType")
    @ResponseBody
    public AjaxResult getDeployType(){
        return AjaxResult.success(Global.getH5DeployType());
    }

    @RequestMapping("/login")
    @ResponseBody
    public AjaxResult ajaxLogin(String username, String password,String mandator, Boolean rememberMe){
        String originalPassword = "";//加密前的密码
        try {
            originalPassword = RsaUtils.decryptByPrivateKey(password);
        } catch (Exception e) {
            return error("请传输加密的密码！");
        }
        CustomUsernamePasswordToken token = new CustomUsernamePasswordToken(username, originalPassword, rememberMe, "", false);
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
            Session session = subject.getSession();
            //添加系统设置信息
            SysSetting systemSet = settingService.querySetting();
            session.setAttribute("systemSet", systemSet);
            //添加需要身份验证的功能
            Map<String, Object> params = new HashMap<String, Object>();
            Map<String, String> authenticationModuleMap = dictionaryForModuleService.queryAuthenticationModule(params);
            session.setAttribute("authenticationModuleMap", authenticationModuleMap);
            //添加委托（被代理）用户
            if (mandator == null || "".equals(mandator) || username.equals(mandator)) {
                session.setAttribute("mandatorUser", ShiroUtils.getSysUser());// 非代理情况，委托人为自己
            } else {
                SysUserInfo mandatorUser = userInfoService.queryByUserId(mandator);
                if (mandatorUser == null) {
                    return error("委托（被代理）用户不存在！");
                }
                if (mandatorUser.getDisabled()) {
                    return error("委托（被代理）用户已被禁用！");
                }
                session.setAttribute("mandatorUser", mandatorUser);
            }

            //拓展用户登录验证（核心验证在SysLoginService类login方法中进行）
            Map<String, Object> exceptions = new HashMap<String, Object>();
            exceptions.put("loginUser", username);    //当前登录用户
            exceptions.put("mandator", mandator);    //委托（被代理）用户
            exceptions.put("serviceTime", new Date());    //中间层服务器时间
            String exceptionmsg = userInfoService.queryUserLoginException(exceptions);
            if (!"".equals(exceptionmsg)) {
                return error(exceptionmsg);
            }

            String userId = ShiroUtils.getUserId();
            String userName = ShiroUtils.getUserId().equals(ShiroUtils.getMandatorId()) ? ShiroUtils.getUserName() : ShiroUtils.getUserName() + "[代理:" + ShiroUtils.getMandatorName() + "]";
            Map<String, Object> mapList = new HashMap<>();
            mapList.put("sessionId", session.getId());
            mapList.put("userId", userId);
            mapList.put("userName", userName);
            mapList.put("roleId", userInfoService.getUserRoleId(userId));
            mapList.put("operateId", userInfoService.getUserRouteCode(userId));
            mapList.put("cid", ShiroUtils.getSysUser().getCid());
            mapList.put("cidName", ShiroUtils.getSysUser().getCidName());
            mapList.put("deptId", ShiroUtils.getSysUser().getDeptId());
            mapList.put("deptName", ShiroUtils.getSysUser().getDeptName());
            mapList.put("deptPath", ShiroUtils.getSysUser().getDeptPath());
            mapList.put("deptPathName", ShiroUtils.getSysUser().getDeptPathName());
            //mapList.put("userModel", ShiroUtils.getSysUser());
            mapList.put("authenticationModuleMap", authenticationModuleMap);
            return AjaxResult.success(mapList);
        } catch (AuthenticationException e) {
            String msg = "用户或密码错误";
            if (StringUtils.isNotEmpty(e.getMessage())) {
                msg = e.getMessage();
            }
            return error(msg);
        }
    }

    /**
     * APP免密登录用
     * @param request
     * @param response
     * @param params
     * @return
     */
    @RequestMapping("/loginByUserInfo")
    @ResponseBody
    public AjaxResult ajaxLoginErp(HttpServletRequest request, HttpServletResponse response, @RequestParam Map<String, Object> params) {
        try {
            SysUserInfo userInfo = JSON.parseObject(params.get("userInfo").toString(), SysUserInfo.class);
            if (userInfo == null) {
                return AjaxResult.error(AjaxResult.Type.ERROR.value(), "非法登录用户，登录失败！");
            } else {
                if (userInfo.getDisabled()) {
                    return AjaxResult.error(AjaxResult.Type.ERROR.value(), "用户已被锁定请联系管理员解锁！");
                }
                String userAgent = request.getHeader("User-Agent");
                Subject subject = SecurityUtils.getSubject();
                subject.logout();
                CustomUsernamePasswordToken token = new CustomUsernamePasswordToken(userInfo.getUserId(), userInfo.getUserPassWord(), false, userAgent, true);
                subject.login(token);
                Session session = subject.getSession();
                //添加系统设置信息
                SysSetting systemSet = settingService.querySetting();
                session.setAttribute("systemSet", systemSet);
                session.setAttribute("mandatorUser", userInfo);
                //添加需要身份验证的功能
                Map<String, String> authenticationModuleMap = dictionaryForModuleService.queryAuthenticationModule(new HashMap<String, Object>());
                //拓展用户登录验证（核心验证在SysLoginService类login方法中进行）
                session.setAttribute("authenticationModuleMap", authenticationModuleMap);
                String userName = ShiroUtils.getUserId().equals(ShiroUtils.getMandatorId()) ? ShiroUtils.getUserName() : ShiroUtils.getUserName() + "[代理:" + ShiroUtils.getMandatorName() + "]";

                Map<String, Object> mapList = new HashMap<>();
                mapList.put("sessionId", session.getId());
                mapList.put("userId", userInfo.getUserId());
                mapList.put("userName", userName);
                mapList.put("cid", ShiroUtils.getSysUser().getCid());
                mapList.put("cidName", ShiroUtils.getSysUser().getCidName());
                mapList.put("deptId", ShiroUtils.getSysUser().getDeptId());
                mapList.put("deptName", ShiroUtils.getSysUser().getDeptName());
                mapList.put("deptPath", ShiroUtils.getSysUser().getDeptPath());
                mapList.put("deptPathName", ShiroUtils.getSysUser().getDeptPathName());
                mapList.put("wxUserId", ShiroUtils.getSysUser().getEnWeChatId());
                //mapList.put("userModel", ShiroUtils.getSysUser());
                mapList.put("authenticationModuleMap", authenticationModuleMap);
                return AjaxResult.success(mapList);
            }
        } catch (AuthenticationException e) {
            String msg = "用户或密码错误！";
            if (StringUtils.isNotEmpty(e.getMessage())) {
                msg = e.getMessage();
            }
            return error(msg);
        }
    }

    /**未登录**/
    @RequestMapping(value = "/unlogin")
    @ResponseBody
    public AjaxResult unlogin()
    {
        return AjaxResult.error(AjaxResult.Type.UNAUTHORIZED.value(), "用户未登录或者登录超时！");
    }

    /**未授权**/
    @RequestMapping(value = "/unauthorized")
    @ResponseBody
    public AjaxResult unauthorized()
    {
        return AjaxResult.error(AjaxResult.Type.FORBIDDEN.value(), "没有权限，请联系管理员授权！");
    }

    /**登出**/
    @RequestMapping(value = "/logout")
    @ResponseBody
    public AjaxResult logout()
    {
        try {
            //退出登录的时候，同时解除钉钉/微信id的绑定
            String userId = ShiroUtils.getSysUser().getUserId();
            userInfoService.updateUserBySyncUnionId(userId,"","");
            Subject subject = SecurityUtils.getSubject();
            subject.logout();
        }catch (Exception ex){

        }
        return AjaxResult.success("登出成功！");
    }
    
    /**
     * 通过用户企业微信ID查询用户信息
     * @param params
     * @return TableDataInfo
     * @author 
     */
    @GetMapping("/queryUserId")
    @ResponseBody
    public TableDataInfo list(@RequestParam Map<String, Object> params){
    	List<SysUserInfo> list = new ArrayList<SysUserInfo>();
        try {
        	list = userInfoService.queryByWeChatId(params.get("wxid").toString());
        } catch (Exception e) {
            e.printStackTrace();
            return getDataTable(this.getExceptionMessage(e).toString());            
        }
        return getDataTable(list);
    }
}
